﻿using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Linq;
using System.Web;

namespace EventumReports
{
    public class ReportInfo
    {
        public ReportInfo()
        {
            _eventumEntities = new eventum2Entities();
        }

        private eventum2Entities _eventumEntities;
        private EventumCategory _eventumCategory;
        private List<EventumUser> _eventumUsers;
        private EventumProject _eventumProject;
        private EventumPriority _eventumPriority;
        private EventumStatus _eventumStatus;
        private List<EventumIssueNotes> _eventumIssueNotes;

        public long Id { get; set; }
        public long CategoryId { get; set; }
        public long ProjectId { get; set; }
        public string Summary { get; set; }
        public string Description { get; set; }
        public long PriorityId { get; set; }
        public long StatusId { get; set; }
        public long? PercentageComplete { get; set; }
        public EventumCategory EventumCategory
        {
            get
            {
                if (this._eventumCategory == null)
                {
                    this._eventumCategory = new EventumCategory();

                    EventumCategory eCat = (from c in _eventumEntities.eventum_project_category
                                             where c.prc_id == this.CategoryId
                                             where c.prc_title != null
                                             select new EventumCategory {Id = c.prc_id, Name = c.prc_title}).FirstOrDefault();
                    if (eCat != null)
                    {
                        if (!string.IsNullOrEmpty(eCat.Name))
                        {
                            this._eventumCategory = eCat;
                        }
                        else
                        {
                            eCat.Name = "Unknow";
                            this._eventumCategory = eCat;
                        }
                    }
                }
                return this._eventumCategory;
            }
            set
            {
                this._eventumCategory = value;
            }
        }
        public List<EventumUser> EventumUsers
        {
            get
            {
                if (this._eventumUsers == null)
                {
                    this._eventumUsers = new List<EventumUser>();

                    List<long> uids =
                        (from esu in _eventumEntities.eventum_issue_user
                         where esu.isu_iss_id == this.Id
                         select esu.isu_usr_id).ToList();

                    foreach (long uid in uids)
                    {
                        this._eventumUsers.Add((from u in _eventumEntities.eventum_user
                                                where u.usr_id == uid
                                                select new EventumUser { Id = u.usr_id, Name = u.usr_full_name }).FirstOrDefault());
                    }
                }
                return this._eventumUsers;
            }
            set
            {
                this._eventumUsers = value;
            }
        }
        public EventumProject EventumProject
        {
            get
            {
                if (this._eventumProject == null)
                {
                    this._eventumProject = new EventumProject();

                    EventumProject eCat = (from prj in _eventumEntities.eventum_project
                                            where prj.prj_id == this.ProjectId
                                           where prj.prj_title != null
                                            select new EventumProject { Id = prj.prj_id, Name = prj.prj_title }).FirstOrDefault();

                    if (eCat != null)
                     {
                         if (!string.IsNullOrEmpty(eCat.Name))
                         {
                             this._eventumProject = eCat;
                         }
                         else
                         {
                             eCat.Name = "Unknow";
                             this._eventumProject = eCat;
                         }
                     }
                }
                return this._eventumProject;
            }
            set
            {
                this._eventumProject = value;
            }
        }
        public EventumPriority EventumPriority
        {
            get
            {
                if (this._eventumPriority == null)
                {
                    this._eventumPriority = new EventumPriority();

                    EventumPriority epri = (from prj in _eventumEntities.eventum_project_priority
                                             where prj.pri_id == this.PriorityId
                                             select new EventumPriority { Id = prj.pri_id, Name = prj.pri_title }).FirstOrDefault();

                    if (epri != null)
                    {
                        if (!string.IsNullOrEmpty(epri.Name))
                        {
                            this._eventumPriority = epri;
                        }
                        else
                        {
                            epri.Name = "Unknow";
                            this._eventumPriority = epri;
                        }
                    }

                }
                return this._eventumPriority;
            }
            set
            {
                this._eventumPriority = value;
            }
        }
        public EventumStatus EventumStatus
        {
            get
            {
                if (this._eventumStatus == null)
                {
                    this._eventumStatus = new EventumStatus();

                    EventumStatus eCat = (from sta in _eventumEntities.eventum_status
                                           where sta.sta_id == this.StatusId
                                            where sta.sta_title != null
                                           select new EventumStatus { Id = sta.sta_id, Name = sta.sta_title }).FirstOrDefault();

                    if (eCat != null)
                    {
                        if (!string.IsNullOrEmpty(eCat.Name))
                        {
                            this._eventumStatus = eCat;
                        }
                        else
                        {
                            eCat.Name = "Unknow";
                            this._eventumStatus = eCat;
                        }
                    }
                    
                }
                return this._eventumStatus;
            }
            set
            {
                this._eventumStatus = value;
            }
        }
        public List<EventumIssueNotes> EventumIssueNotes
        {
            get
            {
                if (this._eventumIssueNotes == null)
                {
                    this._eventumIssueNotes = new List<EventumIssueNotes>();

                    this._eventumIssueNotes = (from ins in _eventumEntities.eventum_note
                                    where ins.not_iss_id == this.Id
                                    select
                                        new EventumIssueNotes
                                        {
                                            Title = ins.not_title,
                                            CreatedBy =
                                                (from cb in
                                                     _eventumEntities.
                                                     eventum_user
                                                 where
                                                     cb.usr_id == ins.not_usr_id
                                                 select cb.usr_full_name).
                                                FirstOrDefault(),
                                            DateCreated = ins.not_created_date,
                                            Description = ins.not_note,
                                        }).ToList();
                }
                return this._eventumIssueNotes;
            }
            set
            {
                this._eventumIssueNotes = value;
            }

        }
        public DateTime DateCreated { get; set; }
        public DateTime DateClosed { get; set; }
        public DateTime DateAction1 { get; set; }
        public DateTime DateAction2 { get; set; }
        public DateTime DateAction3 { get; set; }
        public DateTime DateAction4 { get; set; }
        public DateTime? ExpectedResolutionDate { get; set; }
        
        public List<ReportInfo> GetReportInfo(SearchCriteria searchCriteria)
        {
            #region *** RESULTSET ***

            //List<ReportInfo> result = (List<ReportInfo>) HttpContext.Current.Session["_result"];

            //if (result == null)
            //{
            List<ReportInfo> result = (from eu in _eventumEntities.eventum_issue
                                       where eu.iss_created_date >= searchCriteria.StartDate &&
                                             eu.iss_created_date <= searchCriteria.EndDate
                                       select new ReportInfo
                                                  {
                                                    Id = eu.iss_id,
                                                    DateCreated = eu.iss_created_date,
                                                    DateClosed = eu.iss_closed_date ?? DateTime.Now,
                                                    DateAction1 = eu.iss_last_customer_action_date ?? DateTime.Now,
                                                    DateAction2 = eu.iss_last_internal_action_date ?? DateTime.Now,
                                                    DateAction3 = eu.iss_last_public_action_date ?? DateTime.Now,
                                                    DateAction4 = eu.iss_last_response_date ?? DateTime.Now,
                                                    CategoryId = eu.iss_prc_id,
                                                    ProjectId = eu.iss_prj_id,
                                                    Summary = eu.iss_summary,
                                                    Description = eu.iss_description,
                                                    PriorityId = eu.iss_pri_id,
                                                    StatusId = eu.iss_sta_id,
                                                    PercentageComplete = eu.iss_percent_complete,
                                                    ExpectedResolutionDate = eu.iss_expected_resolution_date
                                                 }).ToList();

            //    HttpContext.Current.Session["_result"] = result;
            //}

            #endregion

            #region *** FILTER CATEGORIES ****

            if (searchCriteria.Categories != null && searchCriteria.Categories.Length > 0 )
            {
                result = (from list in result where list.EventumCategory.Name != null &&  searchCriteria.Categories.Any(c => list.EventumCategory.Name.Contains(c)) select list).ToList();
                //string[] projects = (from list in result where searchCriteria.Categories.Any(c => list.EventumCategory.Name.Contains(c)) select list.EventumProject.Name).ToArray();
            }

            #endregion

            #region *** FILTER PROJECTS ****

            if (searchCriteria.Projects != null && searchCriteria.Projects.Length > 0)
            {
                result = (from list in result where list.EventumProject.Name != null && searchCriteria.Projects.Any(p => list.EventumProject.Name.Contains(p)) select list).ToList();
            }
            
            
            #endregion

            #region *** FILTER STATUS ****

            if (searchCriteria.Statusses != null && searchCriteria.Statusses.Length > 0)
            {
                result = (from list in result
                          where list.EventumStatus.Name != null && searchCriteria.Statusses.Any(s => list.EventumStatus.Name.Contains(s))
                          select list).ToList();
            }

            #endregion

            #region *** FILTER USERS ****

            if (searchCriteria.Users != null && searchCriteria.Users.Length > 0)
            {
                List<ReportInfo> _fUsers = new List<ReportInfo>();
                foreach (ReportInfo reportInfo in result)
                {
                    foreach (EventumUser eventumUser in reportInfo.EventumUsers)
                    {
                        long match =
                            (from sc in searchCriteria.Users where sc == eventumUser.Id select sc).FirstOrDefault();

                        if (match > 0 && !_fUsers.Contains(reportInfo))
                        {
                            _fUsers.Add(reportInfo);
                        }
                    }
                }

                result = _fUsers;
            }

            #endregion

            return result;
        }
    }
    
    public class SearchCriteria
    {
        public long[] Users { get; set; }
        public string[] Projects { get; set; }
        public string[] Categories { get; set; }
        public string[] Statusses { get; set; }
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
    }

    public class EventumUser
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public static List<EventumUser> GetUsers()
        {
            eventum2Entities _eventumEntities = new eventum2Entities();
            return (from eu in _eventumEntities.eventum_user select new EventumUser { Id = eu.usr_id, Name = eu.usr_full_name }).Distinct(d => d.Name).OrderBy(ob => ob.Name).ToList();
        }
    }

    public class EventumProject
    {
        public long Id { get; set; }
        public string Name{ get; set; }

        public static List<EventumProject> GetProjects()
        {
            eventum2Entities _eventumEntities = new eventum2Entities();
            return (from eu in _eventumEntities.eventum_project select new EventumProject { Id = eu.prj_id, Name = eu.prj_title }).Distinct(d => d.Name).OrderBy(ob => ob.Name).ToList();
        }

    }

    public class EventumCategory
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public static List<EventumCategory> GetCategories()
        {
            eventum2Entities _eventumEntities = new eventum2Entities();
            return (from eu in _eventumEntities.eventum_project_category select new EventumCategory { Id = eu.prc_prj_id, Name = eu.prc_title }).Distinct(d => d.Name).OrderBy(ob => ob.Name).ToList();
        }
    }

    public class EventumStatus
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public static List<EventumStatus> GetStatusses()
        {
            eventum2Entities _eventumEntities = new eventum2Entities();
            return (from eu in _eventumEntities.eventum_status select new EventumStatus { Id = eu.sta_id, Name = eu.sta_title }).Distinct(d => d.Name).OrderBy(ob => ob.Name).ToList();
        }
    }

    public class EventumPriority
    {
        public long Id { get; set; }
        public string Name { get; set; }

        public static List<EventumPriority> GetStatusses()
        {
            eventum2Entities _eventumEntities = new eventum2Entities();
            return (from eu in _eventumEntities.eventum_project_priority select new EventumPriority {Id = eu.pri_id, Name = eu.pri_title }).Distinct(d=>d.Name).OrderBy(ob => ob.Name).ToList();
        }
    }

    public class EventumIssueNotes
    {
        public string Title { get; set; }
        public string Description { get; set; }
        public string CreatedBy { get; set; }
        public DateTime? DateCreated { get; set; }
    }
}
